package com.finance.scheduler.service;

import com.finance.framework.lang.BeanUtils;
import com.finance.framework.qurtz.TaskDescriptor;
import org.apache.commons.collections.MapUtils;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by CBWL on 2017/6/2.
 */
@Component
public class TaskFinder implements ApplicationContextAware {
    private ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.context = applicationContext;
    }

    public Map<String, AbstractTask> getAppTasks() {
        Map<String, AbstractTask> claszs =  context.getBeansOfType(AbstractTask.class);
        Map<String,AbstractTask> result = new HashMap<String,AbstractTask>();
        if(MapUtils.isEmpty(claszs)) {
            return result;
        }
        for (Map.Entry<String,AbstractTask>  entry :claszs.entrySet()) {
            if(AopUtils.isCglibProxy(entry.getValue())){
                Class clasz = AopUtils.getTargetClass(entry.getValue());
                try {
                    Object object = clasz.newInstance();
                    BeanUtils.copyProperties(object,entry.getValue());
                    result.put(entry.getKey(), (AbstractTask) object);
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }else{
                result.put(entry.getKey(),entry.getValue());
            }
        }
        return claszs;
    }

    public List<TaskDescriptor> getAppTaskDesciptors() {
        Map<String, AbstractTask> claszs =  context.getBeansOfType(AbstractTask.class);
        List<TaskDescriptor> result = new ArrayList<TaskDescriptor>();
        if(MapUtils.isEmpty(claszs)) {
            return new ArrayList<TaskDescriptor>();
        }
        for(Map.Entry<String,AbstractTask> entry: claszs.entrySet()){
            result.add(entry.getValue().descriptor());
        }
        return result;
    }
}
